package com.kitty.mybatis.mybatisv1.session.defaults;

import com.kitty.mybatis.mybatisv1.exceptions.TooManyResultsException;
import com.kitty.mybatis.mybatisv1.executor.Executor;
import com.kitty.mybatis.mybatisv1.mapping.KittyMappedStatement;
import com.kitty.mybatis.mybatisv1.session.KittyConfiguration;
import com.kitty.mybatis.mybatisv1.session.KittySqlSession;

import java.util.List;

/**
 * 默认的sqlsession实现
 * @Author SHEN
 * @Date 2020/10/20
 */
public class KittyDefaultSqlSession implements KittySqlSession {

    private KittyConfiguration configuration;
    private Executor executor;

    public KittyDefaultSqlSession(KittyConfiguration configuration) {
        this.configuration = configuration;
    }

    @Override
    public <T> T selectOne(String statement, Object param)  {
        List<T> list = selectList(statement, param);
        if (list.size() == 1) {
            return list.get(0);
        } else if (list.size() > 1) {
            throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size());
        } else {
            return null;
        }
    }


    @Override
    public <E> List<E> selectList(String statement, Object parameter) {
        try {
            //根据statement id找到对应的MappedStatement
            KittyMappedStatement ms = configuration.getMappedStatement(statement);
            //转而用执行器来查询结果,注意这里传入的ResultHandler是null
            return executor.query(ms, wrapCollection(parameter));
        } catch (Exception e) {
            //todo 需要进行异常的处理
            //throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
            throw new RuntimeException("Error querying database.  Cause: " + e, e);
        } finally {
            //todo
            //ErrorContext.instance().reset();
        }
    }

    //把参数包装成Collection
    private Object wrapCollection(final Object object) {
        /*if (object instanceof Collection) {
            //参数若是Collection型，做collection标记
            StrictMap<Object> map = new StrictMap<Object>();
            map.put("collection", object);
            if (object instanceof List) {
                //参数若是List型，做list标记
                map.put("list", object);
            }
            return map;
        } else if (object != null && object.getClass().isArray()) {
            //参数若是数组型，，做array标记
            StrictMap<Object> map = new StrictMap<Object>();
            map.put("array", object);
            return map;
        }*/
        //参数若不是集合型，直接返回原来值
        return object;
    }


    @Override
    public <T> T getMapper(Class<T> clazz) {

        return configuration.<T>getMapper(clazz,this);
    }

    public KittyConfiguration getConfiguration() {
        return configuration;
    }
}
